home *** CD-ROM | disk | FTP | other *** search
Text File | 1999-02-04 | 14.7 KB | 467 lines | [TEXT/CWIE] |
- // NetCache Resolver, 1995-96 (C) Mizutori Tetsuya
- // - NCR_Resolve.c, October 8, 1995, May 12 1996
- // Modified: February 2, 1999. (workaround for new format of cache database)
- // This document is pretty printed in 10-point Geneva font.
-
- //#define DEBUG 1
-
- #include "NCR_Basic.h"
- #include "NCR_Resolve.h"
- #include "NCR_File.h"
- #include "NCR_Error.h"
- #ifdef DEBUG
- #include "NCR_Message.h"
- #endif /*DEBUG */
-
- // definition
- // in Header
- #define OFFS_BLOCKSIZE 0x00000C
- #define OFFS_NUMBPAIRS 0x000038
-
- // start with pURL
- #define OFFS_URL_STR 4
-
- // start with pFInfo
- #define OFFS_CACHE_INFO 4
- #define WIDTH_CACHE_INFO 25 // 5*sizeof(long) + 1 + sizeof(long)
- #define OFFS_DATE1 OFFS_CACHE_INFO + 4
- #define OFFS_DATE2 OFFS_CACHE_INFO + 8
- #define OFFS_FILESIZE OFFS_CACHE_INFO + 16
- #define OFFS_CACHE_STR OFFS_CACHE_INFO + WIDTH_CACHE_INFO
-
- #define OFFS_DOC_INFO OFFS_CACHE_STR + 4 /* +#(OFFS_CACHE_STR) */
- //#define WIDTH_DOC_INFO 29 // October 8, 1995; char[1]+long[7]
- #define WIDTH_DOC_INFO 17 // May 12, 1996; char[1]+long[4]
- #define OFFS_DOC_COUNT OFFS_DOC_INFO + WIDTH_DOC_INFO + 4 // +char[1]+long[5]
- #define OFFS_EXPORT_STR OFFS_DOC_INFO + WIDTH_DOC_INFO
- #define OFFS_EXDATA_STR OFFS_EXPORT_STR + 4/* +#(OFFS_EXPORT_STR) */
- // #define OFFS_FORM_STR OFFS_DOC_INFO + WIDTH_DOC_INFO // October 8, 1995
- #define OFFS_FORM_STR OFFS_DOC_INFO+ 4/* +#(OFFS_EXPORT_STR) */ + 4/* +#(OFFS_EXDATA_STR) */
- #define OFFS_TYPE_STR OFFS_FORM_STR + 4 /* +#(OFFS_FORM_STR) */
-
- typedef struct { // If len is zero, then no allocation space for str[] is occupied.
- unsigned long len; // length of string, including the terminator '¥0'
- unsigned char str[]; // character string, teminated by '¥0'
- } QString; // size of QString is at least 4 bytes, which is the case that len is zero.
-
- typedef struct { // length of DummyData record must be determined dynamically
- unsigned char dumchar; // the first filler character
- unsigned char dumstr[];
- } DummyData;
-
- typedef struct {
- unsigned long size; // total size occupied by this record, in bytes
- QString url; // e.g. "http://www.a.b.c/index.html"
- unsigned long _end; // ? = 0x0000 (terminator ?)
- } _URL_Record;
-
-
- typedef struct {
- unsigned long size; // total size occupied by this record, in bytes
- // OFFS_CACHE_INFO
- unsigned long semaphore; // ? = 0x0003 (for NN3), = 0x0005 (for NEW FORMAT).
- unsigned long date1; // time stamp 1 (creation ?)
- unsigned long date2; // time stamp 2 (modification ?)
- unsigned long _2; // ? = 0x0000
- unsigned long filesize; // cache file size, in bytes
- unsigned char _3; // ? = 0x00, odd byte!
- unsigned long _4; // ? = 0x0000 (count-1 for strings followed ?)
- // OFFS_CACHE_STR
- QString cache; // e.g. "cache123000.html"
- // OFFS_DOC_INFO
- /***** October 8, 1995 *****
- unsigned long _5[6]; // ? = {0,1,0,0,0,0}
- unsigned char _6; // ? = 0x00, odd byte!
- unsigned long _7; // ? = 0x0000 or 0x0001 (count-1 for strings followed ?)
- *****/
- /***** May 12, 1995 *****/
- unsigned long _5; // ? = 0x0000
- unsigned char _6; // ? = 0x01, odd byte!
- unsigned long _51; // ? = 0x0000 or 0x0002
- unsigned long _52; // ? = 0x0000 or 0x0008
- unsigned long _53; // ? = 0x0000 or 0x0028
- // OFFS_EXPORT_STR // Following 3 fields (export, exdata, _7) are missing in new format.
- QString export; // e.g. "RC4-Export" (* MISSING *)
- // OFFS_EXDATA_STR
- QString exdata; // e.g. "???Data Export Inc. v.1.0..." (*MISSING *)
- unsigned long _7; // ? = 0x0000 or 0x0001 (count-1 for strings followed ?) (* MISSING *)
- // OFFS_FORM_STR
- QString form; // e.g. "Content-type: application..."
- // OFFS_TYPE_STR
- QString type; // e.g. "text/html"
- unsigned char _8[9]; // ? = {all 0x00's}, odd bytes!
- unsigned long fsize; // cache file size, in bytes (same value to .filesize)
- DummyData _9; // ? = filled by 0x00's, even or odd bytes!
- unsigned long _end; // ? = 0x0000 (terminator ?)
- } _FInfo_Record;
-
-
- typedef struct {
- unsigned long url;
- unsigned long cache;
- unsigned long form;
- unsigned long type;
- unsigned long sizeurl;
- unsigned long sizecache;
- unsigned long sizeform;
- unsigned long sizetype;
- unsigned long filesize;
- unsigned long date1, date2;
- } IndexTableRecord, *IndexTablePtr, **IndexTableHandle;
-
- // prototype
- static unsigned long GetLongLH (unsigned char *p );
-
- static OSErr SetupHeader ( Handle theHndl );
- static OSErr DoHandleCacheData ( Handle theHndlData, Handle theHndl );
- static OSErr MakeRecord ( Handle theHndl, unsigned long startOffset, long index, IndexTableRecord *table );
- static OSErr PrintRecord ( Handle theHndl, long index, IndexTableRecord *table );
- static OSErr InsertRecord ( Handle theHndl, Handle theHndl2, long index, IndexTableRecord *table );
- static OSErr InsertHeader ( Handle theHndl, Handle theHndl2 );
- static OSErr AppendString ( Handle theHndl, const char *str, Size length );
-
- /***** General functions *****/
-
- #define GetWordHL(p) ( (unsigned short) * ( (unsigned short *) (p) ) )
- #define GetLongHL(p) ( (unsigned long) * ( (unsigned long *) (p) ) )
-
- static unsigned long GetLongLH (unsigned char *p )
- {
- unsigned long n = 0;
- unsigned char *q;
-
- q = (unsigned char *) &n;
-
- q[0] = p[3];
- q[1] = p[2];
- q[2] = p[1];
- q[3] = p[0];
-
- return n;
- }
-
- /***** Read Database from the file *****/
- OSErr GetRecordFromFile ( FSSpec *theFSSpec, FInfo *theFInfo, Handle theHndl, long *count )
- {
- Handle theHndlData = nil;
- long datasize;
- OSType fdType = 'DBMC'; // read from 'STR#'
- Str31 strFdType;
- OSErr err = noErr;
-
- // read database from the file
- GetIndString( strFdType, STRID_CACHE, STRIX_CCACHETYPE );
- BlockMove( &strFdType[1], &fdType, 4 );
-
- err = FSpGetFInfo( theFSSpec, theFInfo );
- if ( err != noErr ) { ErrorMessageFS( err, false ); goto out; }
-
- if ( theFInfo->fdType != fdType ) {
- err = errAEWrongDataType;
- ErrorMessageAE( err, false ); goto out; }
-
- theHndlData = NewHandleClear( 0 ); // create a Handle 'theHndlData'
- if ( (err=MemError()) != noErr ) { ErrorMessageMEM( err, true ); }
-
- err = ReadFile( theFSSpec, theFInfo, theHndlData, &datasize );
- if ( err != noErr ) { ErrorMessageFS( err, false ); goto out; }
-
- // convert 'theHndlData' to 'theHndl'
- err = DoHandleCacheData( theHndlData, theHndl );
- *count = GetHandleSize( theHndl );
-
- out:
- if ( theHndlData != nil ) DisposeHandle( theHndlData ); // dispose the Handle 'theHndlData'
-
- return err;
- }
-
-
- /***** do Handle Data *****/
- // globals
- unsigned long gHndlSize = 0; // set by GetHandleSize()
- unsigned long gBlockSize = 0x004000; // read from at the offset 'OFFS_BLOCKSIZE'
-
- static OSErr SetupHeader ( Handle theHndl )
- {
- if ( gHndlSize != 0 ) return noErr;
-
- gHndlSize = GetHandleSize( theHndl );
- gBlockSize = GetLongHL((unsigned char *)*theHndl+OFFS_BLOCKSIZE );
-
- return noErr;
- }
-
-
- static OSErr DoHandleCacheData ( Handle theHndlData, Handle theHndl )
- {
- IndexTableRecord table;
- unsigned long n, index;
- unsigned long startOffset;
- OSErr err;
-
- #ifdef DEBUG
- Message("DoHandleData() start¥n");
- #endif /* DEBUG */
-
- SetupHeader( theHndlData );
-
- InsertHeader( theHndlData, theHndl );
-
- n = 0;
- startOffset = gBlockSize;
- while ( startOffset < gHndlSize ) {
- for ( index=1; ; index++) {
- err = MakeRecord( theHndlData, startOffset, index, &table );
- #ifdef DEBUG
- Message("[%ld] startOffset=$%04X err=%d¥n", index, startOffset, err);
- #endif /* DEBUG */
- if ( err == nilHandleErr ) break;
- if ( err != noErr ) continue;
- // PrintRecord( theHndlData, n, &table );
- InsertRecord( theHndlData, theHndl, n, &table );
- n++;
- }
- startOffset += gBlockSize;
- }
-
- #ifdef DEBUG
- Message("DoHandleData() end¥n");
- #endif /* DEBUG */
- return noErr;
- }
-
- /***** Make Record *****/
- #define ALLOWANCE_TOC 4096
- #define ALLOWANCE_LENGH 255
-
- // index should begin with 1, not 0
- static OSErr MakeRecord ( Handle theHndl, unsigned long startOffset, long index, IndexTableRecord *table )
- {
- long count;
- long offsetURL, offsetFInfo;
- unsigned char *pHeap, *pHashTable, *pURL, *pFInfo;
- long sizeURL, sizeCache, sizeForm, sizeType;
- unsigned char *strURL, *strCache, *strForm, *strType;
- unsigned long filesize, date1, date2;
- unsigned long exportsize, exdatasize;
- unsigned long semaphore; // for new format. February 2, 1999.
- OSErr err = noErr;
-
- HLock( theHndl );
-
- pHeap = (unsigned char *) *theHndl;
- pHashTable = (unsigned char *) *theHndl + startOffset;
- count = GetWordHL(pHashTable);
- if ( count <= 0 || ALLOWANCE_TOC <= count ) { err = nilHandleErr; goto out; }
-
- count /= 2;
- if ( index < 1 || count < index ) { err = nilHandleErr; goto out; }
- index -= 1;
-
- // for URL
- // offsetURL = GetWordHL( pHashTable + 4*index+2 );
- pURL = pHashTable + GetWordHL( pHashTable + 4*index+2 );
-
- //#define OFFS_URL_STR 4
- offsetURL = OFFS_URL_STR;
- sizeURL = GetLongLH(pURL+offsetURL);
- strURL = (unsigned char *) (pURL+offsetURL+sizeof(long));
- #ifdef DEBUG
- Message("strURL: size=%ld¥n", sizeURL);
- #endif /* DEBUG */
- if ( sizeURL <= 0 || ALLOWANCE_LENGH < sizeURL ) { err = paramErr; goto out; }
- offsetURL += sizeof(long) + sizeURL;
-
-
- // for File Info
- pFInfo = pHashTable + GetWordHL( pHashTable + 4*index+4 );
-
- // For NN4 format.
- semaphore = GetLongLH(pFInfo + 4); // '3' for NN3, '5' for NN4. (?)
-
- //#define OFFS_CACHE_INFO 4
- //#define WIDTH_CACHE_INFO 25
- //#define OFFS_CACHE_STR OFFS_CACHE_INFO + WIDTH_CACHE_INFO
- offsetFInfo = OFFS_CACHE_STR;
-
- // cache filename
- sizeCache = GetLongLH(pFInfo+offsetFInfo);
- strCache = (unsigned char *) (pFInfo+offsetFInfo+sizeof(long));
- #ifdef DEBUG
- Message("strCache: size=%ld¥n", sizeCache);
- #endif /* DEBUG */
- if ( sizeCache <= 0 || ALLOWANCE_LENGH < sizeCache ) { err = paramErr; goto out; }
- offsetFInfo += sizeof(long) + sizeCache;
-
- #ifdef COMMENT // October 8, 1995
- //#define OFFS_DOC_INFO OFFS_CACHE_STR + 4 /* +#(OFFS_CACHE_STR) */
- //#define WIDTH_DOC_INFO 29 // char[1]+long[7]
- //#define OFFS_FORM_STR OFFS_DOC_INFO + WIDTH_DOC_INFO
- //#define OFFS_TYPE_STR OFFS_FORM_STR + 4 /* +#(OFFS_FORM_STR) */
- offsetFInfo += WIDTH_DOC_INFO;
- #endif // COMMENT
-
- // May 12, 1996
- //#define OFFS_DOC_INFO OFFS_CACHE_STR + 4 /* +#(OFFS_CACHE_STR) */
- //#define WIDTH_DOC_INFO 17 // char[1]+long[4]
- //#define OFFS_DOC_COUNT OFFS_DOC_INFO + WIDTH_DOC_INFO + 4 // +char[1]+long[5]
- //#define OFFS_EXPORT_STR OFFS_DOC_INFO + WIDTH_DOC_INFO
- //#define OFFS_EXDATA_STR OFFS_EXPORT_STR + 4/* +#(OFFS_EXPORT_STR) */
- //#define OFFS_FORM_STR OFFS_DOC_INFO+ 4/* +#(OFFS_EXPORT_STR) */ + 4/* +#(OFFS_EXDATA_STR) */
- //#define OFFS_TYPE_STR OFFS_FORM_STR + 4 /* +#(OFFS_FORM_STR) */
-
- offsetFInfo += WIDTH_DOC_INFO;
- // For different formats.
- if ( semaphore == 3 ) {
- exportsize = GetLongLH( pFInfo+offsetFInfo );
- offsetFInfo += sizeof(long) + exportsize;
- exdatasize = GetLongLH( pFInfo+offsetFInfo );
- offsetFInfo += sizeof(long) + exdatasize;
- offsetFInfo += sizeof(long);
- } else if ( semaphore == 5 ) {
- // These 3 fields (export, exdata, (long)) are missing in new format.
- // do nothing.
- }
-
- // content-type (Can be Null string!)
- sizeForm = GetLongLH( pFInfo+offsetFInfo );
- strForm = (unsigned char *) (pFInfo+offsetFInfo+sizeof(long));
- #ifdef DEBUG
- Message("strForm: size=%ld¥n", sizeForm);
- #endif /* DEBUG */
- if ( sizeForm < 0 || ALLOWANCE_LENGH < sizeForm ) { err = paramErr; goto out; }
- offsetFInfo += sizeof(long) + sizeForm;
-
- // type (Can be Null string!)
- sizeType = GetLongLH( pFInfo+offsetFInfo );
- strType = (unsigned char *) (pFInfo+offsetFInfo+sizeof(long));
- #ifdef DEBUG
- Message("strType: size=%ld¥n", sizeType);
- #endif /* DEBUG */
- if ( sizeType < 0 || ALLOWANCE_LENGH < sizeType ) { err = paramErr; goto out; }
- offsetFInfo += sizeof(long) + sizeType;
-
- table->url = (unsigned long) strURL - (unsigned long) pHeap;
- table->cache = (unsigned long) strCache - (unsigned long) pHeap;
- table->form = (unsigned long) strForm - (unsigned long) pHeap;
- table->type = (unsigned long) strType - (unsigned long) pHeap;
- table->sizeurl = ( sizeURL < 1 ? 0 : sizeURL - 1 ) ; // truncate the terminator '¥0'
- table->sizecache = ( sizeCache < 1 ? 0 : sizeCache - 1 );
- table->sizeform = ( sizeForm < 1 ? 0 : sizeForm - 1 );
- table->sizetype = ( sizeType < 1 ? 0 : sizeType - 1 );
- table->date1 = GetLongLH( pFInfo+OFFS_DATE1 );
- table->date2 = GetLongLH( pFInfo+OFFS_DATE2 );
- table->filesize = GetLongLH( pFInfo+OFFS_FILESIZE );
- //#define OFFS_DATE1 OFFS_CACHE_INFO + 4
- //#define OFFS_DATE2 OFFS_CACHE_INFO + 8
- //#define OFFS_FILESIZE OFFS_CACHE_INFO + 16
-
- #ifdef DEBUG
- Message("done¥n");
- #endif /* DEBUG */
-
- out:
- HUnlock( theHndl );
- return err;
- }
-
-
- static OSErr PrintRecord ( Handle theHndl, long index, IndexTableRecord *table )
- {
- unsigned char *pHeap;
-
- HLock( theHndl );
- pHeap = (unsigned char *) *theHndl;
-
- #ifdef DEBUG
- Message("[%ld] cache=$%04X url=$%04X type=$%04X size=%ld¥n",
- index, (short) table->cache, (short) table->url, (short) table->type, table->filesize);
- Message("Cache:%ld('%s') ", table->sizecache, pHeap+table->cache);
- Message("Type:%ld('%s')¥n", table->sizetype, pHeap+table->type);
- Message("URL:%ld('%s')¥n", table->sizeurl, pHeap+table->url);
- #endif /* DEBUG */
-
- HUnlock( theHndl );
-
- return noErr;
- }
-
-
- #define TAB "¥t"
- #define EOL "¥r"
-
- static OSErr InsertRecord ( Handle theHndl, Handle theHndl2, long index, IndexTableRecord *table )
- {
- unsigned char *pHeap;
- Str255 text;
-
- HLock( theHndl );
- pHeap = (unsigned char *) *theHndl;
-
- // for item 1 (some code '0')
- AppendString( theHndl2, "0" TAB, 2 );
- // for item 2 (date1)
- NumToString(table->date1, text);
- AppendString( theHndl2, (char *) &text[1], text[0] );
- AppendString( theHndl2, TAB, 1 );
- // for item 3 (date2)
- NumToString(table->date2, text);
- AppendString( theHndl2, (char *) &text[1], text[0] );
- AppendString( theHndl2, TAB, 1 );
- // for item 4 ("cache12300")
- AppendString( theHndl2, (char *) pHeap+table->cache, table->sizecache );
- AppendString( theHndl2, TAB, 1 );
- // for item 5 ("URL")
- AppendString( theHndl2, (char *) pHeap+table->url, table->sizeurl );
- AppendString( theHndl2, TAB, 1 );
- // for item 6 (file/type)
- AppendString( theHndl2, (char *) pHeap+table->type, table->sizetype );
- AppendString( theHndl2, TAB, 1 );
- // for item 7 (format ?)
- // AppendString( theHndl2, (char *) pHeap+table->form, table->sizeform );
- AppendString( theHndl2, TAB, 1 );
- // for item 8 (file size)
- NumToString(table->filesize, text);
- AppendString( theHndl2, (char *) &text[1], text[0] );
- // for item 9 thru 10 (empty items)
- AppendString( theHndl2, TAB TAB, 2 );
- // for CR
- AppendString( theHndl2, EOL, 1 );
-
- HUnlock( theHndl );
-
- return noErr;
- }
-
- static OSErr InsertHeader ( Handle theHndl, Handle theHndl2 )
- {
- Str255 text;
-
- // for header line
- GetIndString( text, STRID_CACHE, STRIX_FORMAT );
- AppendString( theHndl2, (char *) &text[1], text[0] );
- // for CR
- AppendString( theHndl2, EOL, 1 );
-
- return noErr;
- }
-
- static OSErr AppendString ( Handle theHndl, const char *str, Size length )
- {
- unsigned long n;
- OSErr err;
-
- n = GetHandleSize( theHndl );
-
- SetHandleSize( theHndl, n+length );
- if ( (err=MemError()) != noErr )
- ErrorMessageMEM( err, true );
-
- BlockMove( str, (unsigned char *) *theHndl + n, length );
-
- return err;
- }
-
- // end of program
-